package com.midele.goodstuff.util

import android.content.Context
import android.util.Log
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.*
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.runBlocking
import java.io.IOException

// 通过属性委托创建 DataStore 实例 (推荐方式)
// "app_preferences" 是 DataStore 文件的名称
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "app_preferences")

object DataStoreUtils {

    private const val TAG = "DataStoreUtils"

    // --- 写入数据 ---

    suspend fun <T> saveData(context: Context, key: Preferences.Key<T>, value: T) {
        try {
            context.dataStore.edit { preferences ->
                preferences[key] = value
            }
        } catch (e: IOException) {
            Log.e(TAG, "Error writing preferences: ${key.name}", e)
            // 可选: 抛出自定义异常或处理错误
        } catch (e: Exception) {
            Log.e(TAG, "Unexpected error writing preferences: ${key.name}", e)
        }
    }

    // --- 读取数据 ---

    /**
     * 读取指定类型的数据.
     * @param context Context
     * @param key Preferences.Key<T>
     * @param defaultValue T 默认值，如果键不存在或读取失败
     * @return Flow<T> 包含读取到的值或默认值
     */
    fun <T> readData(context: Context, key: Preferences.Key<T>, defaultValue: T): Flow<T> {
        return context.dataStore.data
            .catch { exception ->
                // IOException意味着读取数据时发生错误。
                // 如果是其他类型的异常，最好重新抛出它。
                if (exception is IOException) {
                    Log.e(TAG, "Error IOException reading preferences: ${key.name}", exception)
                    emit(emptyPreferences()) // 发射空偏好设置以使用默认值
                } else {
                    Log.e(TAG, "Error other error reading preferences: ${key.name}", exception)
                    throw exception
                }
            }
            .map { preferences ->
                LogUtils.d(TAG, "preferences --->: ${preferences[key]}")
                val dataC = preferences[key] ?: defaultValue
                dataC
            }
    }

    /**
     * 同步读取指定类型的数据 (阻塞当前线程).
     * 仅在你知道不会阻塞UI线程或在后台线程中调用时使用。
     * 推荐使用异步的 readData(key, defaultValue): Flow<T>.
     *
     * @param context Context
     * @param key Preferences.Key<T>
     * @param defaultValue T 默认值
     * @return T 读取到的值或默认值
     */
    fun <T> readDataBlocking(context: Context, key: Preferences.Key<T>, defaultValue: T): T {
        return runBlocking { // 注意：这会阻塞调用线程
            readData(context, key, defaultValue).first()
        }
    }

    // --- 移除数据 ---

    suspend fun <T> removeData(context: Context, key: Preferences.Key<T>) {
        try {
            context.dataStore.edit { preferences ->
                preferences.remove(key)
            }
        } catch (e: IOException) {
            Log.e(TAG, "Error removing preference: ${key.name}", e)
        } catch (e: Exception) {
            Log.e(TAG, "Unexpected error removing preference: ${key.name}", e)
        }
    }

    // --- 清除所有数据 ---

    suspend fun clearAllData(context: Context) {
        try {
            context.dataStore.edit { preferences ->
                preferences.clear()
            }
        } catch (e: IOException) {
            Log.e(TAG, "Error clearing all preferences", e)
        } catch (e: Exception) {
            Log.e(TAG, "Unexpected error clearing all preferences", e)
        }
    }

    suspend fun clearLoginData(context: Context) {
        try {
            context.dataStore.edit { preferences ->
                preferences.remove(PrefKeys.TOKEN)
                preferences.remove(PrefKeys.COOKIE_DATA)
                preferences.remove(PrefKeys.USER_INFO)
                preferences.remove(PrefKeys.USER_NAME)
                preferences.remove(PrefKeys.USER_ID)
                preferences.remove(PrefKeys.SEARCH_HISTORY)
            }
        } catch (e: IOException) {
            Log.e(TAG, "Error clearing all preferences", e)
        } catch (e: Exception) {
            Log.e(TAG, "Unexpected error clearing all preferences", e)
        }
    }

    suspend fun clearLoginDataNoUserId(context: Context) {
        try {
            context.dataStore.edit { preferences ->
                preferences.remove(PrefKeys.TOKEN)
                preferences.remove(PrefKeys.COOKIE_DATA)
                preferences.remove(PrefKeys.USER_INFO)
                preferences.remove(PrefKeys.SEARCH_HISTORY)
            }
        } catch (e: IOException) {
            Log.e(TAG, "Error clearing all preferences", e)
        } catch (e: Exception) {
            Log.e(TAG, "Unexpected error clearing all preferences", e)
        }
    }

    object PrefKeys {
        val USER_NAME = stringPreferencesKey("user_name")
        val USER_ID = intPreferencesKey("user_id")
        val DEVICE_ID = stringPreferencesKey("device_id")
        val TOKEN = stringPreferencesKey("token")
        val IS_READ_PRIVACY = booleanPreferencesKey("is_read_privacy")
        val COOKIE_DATA = stringPreferencesKey("cookie_data")
        val USER_INFO = stringPreferencesKey("user_info")
        val SEARCH_HISTORY = stringPreferencesKey("search_history")
        val MIN_PRICE = doublePreferencesKey("minPrice")
        val SHARE_LINK_ID = stringPreferencesKey("share_link_id")
        val IS_TEENAGE_MODE = booleanPreferencesKey("is_teenage_mode")
        val TEENGE_MODE_PASSWORD = stringPreferencesKey("teenge_mode_password")
    }
}